package com.nhim.cms.util;

import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.nhim.cms.ElementTemplateHelper;
import com.nhim.cms.dao.ElementDefinitionDAO;
import com.nhim.cms.domain.ElementDefinition;
import com.nhim.cms.domain.ElementTemplate;

@Service
public class ElementDefinitionManager {

	@Autowired
	private ElementDefinitionDAO elementDefinitionDAO;

	@Autowired
	ElementTemplateManager elementTemplateManager;


	@PostConstruct
	public void init() throws Exception {
	}

	@PreDestroy
	public void destroy() {
	}

	@Transactional(readOnly = true)
	public ElementDefinition findById(Integer id) {

		return elementDefinitionDAO.findById(id);

	}

	@Transactional(readOnly = true)
	public List<ElementDefinition> findAll() {
		return elementDefinitionDAO.findAll();
	}

	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void save(ElementDefinition entity) throws Exception {
		elementDefinitionDAO.save(entity);
	}

	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public Boolean delete(Integer id) throws Exception {
		ElementDefinition elementDefinition = elementDefinitionDAO.findById(id);
		if (elementDefinition != null) {
			beforeDelete(id);
			elementDefinitionDAO.delete(elementDefinition);
			return true;
		}
		return false;
	}

	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public ElementDefinition saveOrUpdate(ElementDefinition entity)
			throws Exception {

		ElementDefinition saveElement = elementDefinitionDAO
				.saveOrUpdate(entity);
		// add the default template
		if (saveElement.getElementTemplates() == null
				|| saveElement.getElementTemplates() != null
				&& saveElement.getElementTemplates().size() == 0) {
			ElementTemplate template = ElementTemplateHelper
					.getDefaultTemplate(saveElement.getElementType());
			template.setElementDefinition(saveElement);
			elementTemplateManager.saveOrUpdate(template);
		}
		return saveElement;

	}

	@Transactional(readOnly = true)
	public List<ElementDefinition> findElementDefinitionEntriesBySearch(
			String startsWith, String orderBy) {
		return elementDefinitionDAO.findElementDefinitionEntriesBySearch(
				startsWith, orderBy);
	}

	@Transactional(readOnly = true)
	public Integer countElementDefinitionsBySearch(String startsWith) {
		return elementDefinitionDAO.countElementDefinitionsBySearch(startsWith);
	}

	@Transactional(readOnly = true)
	public ElementDefinition findByName(String name) {
		return elementDefinitionDAO.findByName(name);
	}

	public static ElementDefinitionManager getFromApplicationContext(
			ApplicationContext ctx) {
		return (ElementDefinitionManager) ctx
				.getBean(ElementDefinitionManager.class);
	}

	/*-----------------Region Private Method ------------------------------*/
	private void beforeDelete(Integer id) throws Exception {
		try {
			List<ElementTemplate> results = elementTemplateManager
					.findByElementDefinitionId(id);
			for (ElementTemplate template : results) {
				elementTemplateManager.delete(template);
			}
		} catch (Exception e) {
			throw e;
		}

	}

}
